home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Libris Britannia 4
/
science library(b).zip
/
science library(b)
/
PROGRAMM
/
PASCAL
/
0514.ZIP
/
CRAYZ15.ARC
/
VSGEDI.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1986-08-01
|
7KB
|
162 lines
{ Copyright (C) 1986 Adam Fritz, 133 Main St., Afton, NY 13730 }
procedure vSGEDI ( var fID ;
lda, n : integer ;
var IPvt : IVECTOR ;
var Det : DVECTOR ;
var Work : VECTOR ;
JobCode : integer ) ;
{ PROGRAM: }
{ }
{ SGEDI - computes the determinant and inverse of }
{ a matrix using the factors computed by }
{ SGECO or SGEFA. }
{ }
{ VERSION: DATE: }
{ }
{ 1.4/TURBO Pascal 3.0 08/02/86 }
{ FORTRAN 08/14/78 }
{ }
{ DESCRIPTION: }
{ }
{ On entry; }
{ }
{ A - Output from SGECO or SGEFA. }
{ lda - Leading dimension of matrix A. }
{ n - Order of matrix A. }
{ IPvt - Pivot index vector from SGECO or }
{ SGEFA. }
{ Work - Work vector. Contents destroyed. }
{ JobCode - }
{ =11 compute determinant and inverse. }
{ =01 compute inverse only. }
{ =10 compute determinant only. }
{ }
{ On return; }
{ }
{ A - Inverse of original matrix if }
{ requested, otherwise unchanged. }
{ Det - Determinant of original matrix if }
{ requested, otherwise ignored; }
{ determinant = Det[1]*10**Det[2] }
{ with; }
{ 1.0 <= abs(Det[1]) < 10.0 }
{ or }
{ Det[1] = 0.0. }
{ }
{ Error condition; }
{ }
{ Division by zero will occur if the input }
{ factor contains a zero on the diagonal and }
{ the inverse is requested. It will not occur }
{ if the subroutines are called correctly and }
{ if SGECO has set RCond > 0.0 or SGEFA has }
{ set InfoCode = 0. }
{ }
{ SUBPROGRAMS: }
{ }
{ SAXPY from BLAS }
{ SSCAL from BLAS }
{ SSWAP from BLAS }
{ }
{ AUTHORS: }
{ }
{ Cleve Moler }
{ University of New Mexico }
{ Argonne National Laboratories }
{ }
{ PASCAL translation; }
{ }
{ Adam Fritz }
{ 133 Main Street }
{ Afton, New York 13730 }
const
TEN : real = 10.0 ;
iTEN : integer = 10 ;
var
gID : vARRAY Absolute fID ;
d : real ;
e : integer ;
t : real ;
i, j, k, l : integer ;
kb, kp1, nm1 : integer ;
begin
{ Compute Determinant }
if (JobCode div iTEN) <> 0 then begin
d := 1.0 ;
e := 0 ;
i := 0 ;
while (i < n) and (d <> 0.0) do begin
i := i + 1 ;
if IPvt[i] <> i then
d := -d ;
iAk := VectorRead(gID,n,i,i,1,Ak) ;
d := Ak[iAk] * d ;
if d <> 0.0 then
if Abs(d) < 1.0 then
repeat
d := TEN * d ;
e := e - 1
until Abs(d) >= 1.0
else if Abs(d) >= 10.0 then
repeat
d := d/TEN ;
e := e + 1
until Abs(d) < 10.0
end ;
Det[1] := d ;
Det[2] := e
end ;
{ Compute inverse(U) }
if (JobCode mod iTEN) <> 0 then begin
for k := 1 to n do begin
iAk := VectorRead (gID,n,1,k,k,Ak) ;
Ak[iAk+k-1] := 1.0/Ak[iAk+k-1] ;
t := -Ak[iAk+k-1] ;
SSCAL (k-1, t, Ak[iAk], 1) ;
VectorWrite (gID,n,1,k,k,Ak) ;
if n > k then begin
kp1 := k + 1 ;
for j := kp1 to n do begin
iAj := VectorRead (gID,n,1,j,k,Aj) ;
t := Aj[iAj+k-1] ;
Aj[iAj+k-1] := 0.0 ;
SAXPY (k, t, Ak[iAk], 1, Aj[iAj], 1) ;
VectorWrite (gID,n,1,j,k,Aj) ;
end
end
end ;
{ Form inverse(U) * inverse(L) }
if n > 1 then begin
nm1 := n - 1 ;
for kb := 1 to nm1 do begin
k := n - kb ;
kp1 := k + 1 ;
iAk := VectorRead (gID,n,1,k,n,Ak) ;
for i := kp1 to n do begin
Work[i] := Ak[iAk+i-1] ;
Ak[iAk+i-1] := 0.0
end ;
for j := kp1 to n do begin
t := Work[j] ;
iAj := VectorRead (gID,n,1,j,n,Aj) ;
SAXPY(n, t, Aj[iAj], 1, Ak[iAk], 1)
end ;
l := IPvt[k] ;
if l <> k then begin
iAl := VectorRead (gID,n,1,l,n,Al) ;
VectorWrite (gID,n,1,l,n,Ak) ;
VectorWrite (gID,n,1,k,n,Al)
end
else
VectorWrite (gID,n,1,k,n,Ak) ;
end
end
end
end ;
{ Copyright (C) 1986 Adam Fritz, 133 Main St., Afton, NY 13730 }